package com.example.qt.ptplatform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.qt.ptplatform.entity.*;
import com.example.qt.ptplatform.mapper.*;
import com.example.qt.ptplatform.service.TorrentService;
import com.example.qt.ptplatform.service.UserService;
import io.pinecone.clients.Index;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;
import io.pinecone.clients.Pinecone;
import org.openapitools.db_data.client.ApiException;

@Service
public class TorrentServiceImpl extends ServiceImpl<TorrentMapper, Torrent> implements TorrentService {

    @Autowired
    private TorrentMapper torrentMapper; // 注入 TorrentMapper

    @Autowired
    private UserMapper userMapper; // 注入 UserMapper 来查询用户角色

    @Autowired
    private SeedMapper seedMapper; // 注入 SeedMapper 来查询用户是否为该种子的上传者

    @Autowired
    private DownloadMapper downloadMapper;

    @Lazy
    @Autowired
    private UserService userService; // 添加UserService的注入

    private final Pinecone pinecone;

    @Autowired
    private FavoriteTorrentMapper favoriteTorrentMapper;
    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    public TorrentServiceImpl(Pinecone pinecone) {
        this.pinecone = pinecone;
    }

    public List<Torrent> findAllTorrentList() {
        return torrentMapper.selectList(null);
    }

    @Override
    public List<Torrent> findTorrentList(String tags) {

        LambdaQueryWrapper<Torrent> wrapper= new LambdaQueryWrapper<>();
        if (tags!=null && !"".equals(tags) && !tags.trim().isEmpty() ) {
            wrapper.like(Torrent::getTags,tags);
        }
        return torrentMapper.selectList(wrapper);
    }

    @Override
    public Torrent getTorrentDetailsById(int torrentId) {
        // 获取种子基本信息
        Torrent torrent = torrentMapper.selectById(torrentId);
        if (torrent == null) {
            return null;
        }

        // 获取并设置用户名
        if (torrent.getUserId() != null) {
            User user = userService.getById(torrent.getUserId());
            if (user != null) {
                torrent.setUserName(user.getUsername());
            }
        }

        return torrent;
    }


    // 删除种子的逻辑
    public String deleteTorrent(int userId, int torrentId) {
        // 1. 判断种子是否存在
        Torrent torrent = torrentMapper.selectById(torrentId);
        if (torrent == null) {
            // 如果种子不存在，返回种子不存在的错误信息
            return "TRORENT_NOT_FOUND";
        }

        // 2. 判断用户是否为管理员
        User user = userMapper.selectById(userId);
        if (user != null && "admin".equals(user.getRole())) {
            // 如果是管理员，先删除 seeding 表中的相关记录
            seedMapper.delete(new QueryWrapper<Seed>().eq("torrent_id", torrentId));

            // 删除 torrent
            torrentMapper.deleteById(torrentId);
            deleteTorrentFromPinecone(torrentId);
            return "SUCCESS";
        }

        // 3. 判断用户是否为该种子的上传者
        Seed seed = seedMapper.selectOne(new QueryWrapper<Seed>().eq("torrent_id", torrentId).eq("user_id", userId));
        if (seed != null) {
            // 3.1 删除评论记录（comments表）
            commentMapper.delete(new QueryWrapper<Comments>().eq("torrent_id", torrentId));
            // 删除下载记录（downloads表）
            downloadMapper.delete(new QueryWrapper<Download>().eq("torrent_id", torrentId));
            // 删除收藏表中的相关记录
            QueryWrapper<FavoriteTorrent> favoriteWrapper = new QueryWrapper<>();
            favoriteWrapper.eq("torrent_id", torrentId);
            favoriteTorrentMapper.delete(favoriteWrapper);
            // 如果用户是上传者，先删除 seeding 表中的相关记录
            seedMapper.delete(new QueryWrapper<Seed>().eq("torrent_id", torrentId));

            // 删除 torrent
            torrentMapper.deleteById(torrentId);
            deleteTorrentFromPinecone(torrentId);
            return "SUCCESS";
        }

        // 如果都不是，返回无权限删除的错误信息
        return "NO_PERMISSION";
    }

    public void deleteTorrentFromPinecone(int torrentId) {
        // 以下是松果向量库的删除部分
        String indexName = "ptplatform-recommendations";
        String namespace = "__default__";  // 使用相同的 namespace

        // 获取 Pinecone 索引连接
        Index index = pinecone.getIndexConnection(indexName);

        if (index == null) {
            System.out.println("Pinecone 索引连接失败！");
        } else {
            System.out.println("Pinecone 索引连接成功！");
        }

        // 将 int torrentId 转换为 String，并创建 ID 列表
        List<String> idsToDelete = new ArrayList<>();
        idsToDelete.add("torrent-" + torrentId);  // 创建 ID 列表，假设 ID 格式为 "torrent-{torrentId}"

        // 使用 deleteByIds 删除数据
        index.deleteByIds(idsToDelete, namespace);

        System.out.println("已删除数据: " + idsToDelete);

    }


    // 获取用户上传的种子列表
    public List<Torrent> getUserTorrents(int userId) {
        // 使用 MyBatis-Plus 提供的查询方法，查找该用户上传的所有种子
        return torrentMapper.selectList(new QueryWrapper<Torrent>().eq("user_id", userId));
    }


    public boolean uploadCoverImage(Integer torrentId, MultipartFile coverImageFile) {
        try {
            // 获取封面图片的二进制数据
            byte[] coverImageData = coverImageFile.getBytes();

            // 更新数据库中的封面图片数据
            Torrent torrent = this.getById(torrentId);
            if (torrent != null) {
                torrent.setCoverImage(coverImageData);
                return this.updateById(torrent); // 更新数据库
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    // 获取tags集合的Jaccard相似度
    private double calculateJaccardSimilarity(Set<String> tags1, Set<String> tags2) {
        Set<String> intersection = new HashSet<>(tags1);
        intersection.retainAll(tags2);
        Set<String> union = new HashSet<>(tags1);
        union.addAll(tags2);
        return (double) intersection.size() / union.size();
    }

    // 推荐视频的方法
    public List<Torrent> recommendVideos(Integer torrentId) {
        // 获取当前视频的tags
        Torrent currentTorrent = this.getById(torrentId);
        if (currentTorrent == null) {
            throw new RuntimeException("未找到该资源");
        }
        Set<String> currentTags = new HashSet<>(Arrays.asList(currentTorrent.getTags().split(",")));

        // 获取所有视频并计算相似度
        List<Torrent> allTorrents = this.list();  // 获取所有视频资源
        List<TorrentSimilarity> similarities = new ArrayList<>();

        for (Torrent torrent : allTorrents) {
            if (torrent.getTorrentId().equals(torrentId)) {
                continue;  // 跳过自己
            }

            Set<String> tags = new HashSet<>(Arrays.asList(torrent.getTags().split(",")));
            double similarity = calculateJaccardSimilarity(currentTags, tags);

            similarities.add(new TorrentSimilarity(torrent, similarity));
        }

        // 按照相似度排序并返回前三个
        similarities.sort((a, b) -> Double.compare(b.getSimilarity(), a.getSimilarity()));
        return similarities.stream()
                .limit(3)
                .map(TorrentSimilarity::getTorrent)
                .collect(Collectors.toList());
    }

    // 用来包装torrent和相似度的辅助类
    static class TorrentSimilarity {
        private Torrent torrent;
        private double similarity;

        public TorrentSimilarity(Torrent torrent, double similarity) {
            this.torrent = torrent;
            this.similarity = similarity;
        }

        public Torrent getTorrent() {
            return torrent;
        }

        public double getSimilarity() {
            return similarity;
        }
    }

    // 根据关键字搜索标题和描述
    public List<Torrent> searchTorrents(String keyword) {
        // 根据 title 查找匹配的记录
        List<Torrent> titleResults = torrentMapper.findByTitleContaining(keyword);

        // 根据 description 查找匹配的记录
        List<Torrent> descriptionResults = torrentMapper.findByDescriptionContaining(keyword);

        // 使用 HashSet 去重，防止重复记录
        Set<Torrent> resultSet = new HashSet<>(titleResults);
        resultSet.addAll(descriptionResults);

        // 将结果转换为 List 并返回
        return new ArrayList<>(resultSet);
    }

    // 根据关键字搜索标题和描述
    public List<Torrent> searchTorrentsByKeyword(String keyword) {
        List<Torrent> titleResults = torrentMapper.findByTitleContaining(keyword);
        List<Torrent> descriptionResults = torrentMapper.findByDescriptionContaining(keyword);

        Set<Torrent> resultSet = new HashSet<>(titleResults);
        resultSet.addAll(descriptionResults);

        return new ArrayList<>(resultSet);
    }

    // 根据 tags 关键字筛选记录
    public List<Torrent> searchTorrentsByTag(String tag) {
        return torrentMapper.findByTagsContaining(tag);
    }


}
